﻿using Frogsoft.Data;
using Frogsoft.Domain.Permission;
using Frogsoft.Permission.Consts;
using Frogsoft.Permission.Dtos;
using Microsoft.AspNetCore.Identity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;

namespace Frogsoft.Permission
{
    public class PermissionService
    {
        private readonly RoleManager<IdentityRole>? _roleManager;
        private UserManager<AppUser>? _userManager;
        private MyContext _myContext;
        public PermissionService(RoleManager<IdentityRole>? roleManager, UserManager<AppUser>? userManager, MyContext myContext)
        {
            _roleManager = roleManager;
            _userManager = userManager;
            _myContext = myContext;
        }

        public async Task<List<PermissionTreeDto>> GetUserPermissionAsTree(List<string> claimList)
        {
            var query = from t1 in StaticPermissions.PermissionList
                        join t2 in claimList.Distinct() on t1.PermissionName equals t2 into tmp
                        from claimText in tmp.DefaultIfEmpty()
                        select new PermissionItem
                        {
                            PermissionName = t1.PermissionName,
                            PermissionDesc = t1.PermissionDesc,
                            PermissionType = t1.PermissionType,
                            Parent = t1.Parent,
                            ViewPath = t1.ViewPath,
                            isGrant = claimText is not null
                        };
            var result = query.Where(o => o.isGrant == true && (o.PermissionType == "菜单" || o.PermissionType == "页面"));
            return await GetPermissionTree("0", result.ToList());
        }



        public async Task<IEnumerable<PermissionTreeDto>> GetAllPermissionAsTree(string roleId)
        {
            var role = await _roleManager.FindByIdAsync(roleId);
            var claims =await  _roleManager.GetClaimsAsync(role);
            var claimList = claims.Select(o => new string(o.Type)).ToList();
            var result = from t1 in StaticPermissions.PermissionList
                         join t2 in claimList on t1.PermissionName equals t2 into tmp
                         from claimText in tmp.DefaultIfEmpty()
                         select new PermissionItem
                         {
                             PermissionName = t1.PermissionName,
                             PermissionDesc = t1.PermissionDesc,
                             PermissionType = t1.PermissionType,
                             Parent = t1.Parent,
                             ViewPath = t1.ViewPath,
                             isGrant = claimText is not null
                         };
            return await GetPermissionTree("0", result.ToList());
        }

        public async Task<List<PermissionTreeDto>> GetPermissionTree(string pid, IEnumerable<PermissionItem> items)
        {
            var treeNodes = items.Where(o => o.Parent == pid).Select(m => new PermissionTreeDto
            {
                Id = m.PermissionName,
                Text = m.PermissionDesc,
                parentId = m.Parent,
                permission_type = m.PermissionType,
                LAY_CHECKED = m.isGrant,
                viewPath = m.ViewPath
            }).ToList();
            foreach (PermissionTreeDto treeNode in treeNodes)
            {
                var subTreeNodes = await GetPermissionTree(treeNode.Id, items);
                if (subTreeNodes.Count() > 0)
                {
                    treeNode._Items.AddRange(subTreeNodes);
                }
            }
            return treeNodes;
        }


        public void UpdatePermission(string roleId, List<PermissionTreeDto> permissions)
        {
            var oldClaims = _myContext.RoleClaims.Where(o => o.RoleId == roleId).ToList();
            var newClaims = new List<IdentityRoleClaim<string>>();
            foreach (var permission in permissions)
            {
                var newClaim = new IdentityRoleClaim<string>();
                newClaim.RoleId = roleId;
                newClaim.ClaimType = permission.Id;
                newClaim.ClaimValue = "";
                newClaims.Add(newClaim);
            }
            _myContext.RoleClaims.RemoveRange(oldClaims);
            _myContext.RoleClaims.AddRange(newClaims);
            _myContext.SaveChanges();
        }
    }
}
